Add UnifiedPush support with PushProvider abstraction#2
Open
sk7n4k3d wants to merge 26 commits into
Open
Conversation
7510038 to
cebb60c
Compare
…ocket Introduces a PushProvider abstraction layer that allows different push notification backends to be plugged in via Dagger multibinding. This addresses the review feedback requesting a scalable, generic interface similar to the SensorManager pattern. - PushProvider interface with priority-based selection - PushProviderManager for runtime provider selection and registration - FcmPushProvider (full flavor), UnifiedPushProvider, WebSocketPushProvider - Dagger modules for full and minimal flavor bindings Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…sing - PushProviderManagerTest: provider selection, priority ordering, registration, server updates, provider switching - PushProviderTest: interface contract, default values, data class behavior - UnifiedPushMessageParsingTest: JSON deserialization for notification payloads (actions, nested data, registration_info, confirm_id) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ttingsPresenter Replace direct UnifiedPush/FCM token calls with PushProviderManager in: - LaunchActivity: onOnboardingComplete uses selectAndRegister() - LaunchPresenterImpl (full/minimal): resyncRegistration uses selectAndRegister() - LaunchPresenterBase: accepts PushProviderManager as constructor param - SettingsPresenterImpl: addServer uses selectAndRegister() This completes the wiring of the generic PushProvider interface into the existing codebase, removing direct dependencies on UnifiedPush connector and getMessagingToken() from these classes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rror handling - Fix pushEncrypt condition in IntegrationRepositoryImpl that was inverted: encryption was only applied for FCM URLs instead of UnifiedPush URLs. Now passes through the provider's encrypt flag directly. - Fix FcmPushProvider.isActive() to return false when UnifiedPush is enabled, preventing incorrect provider detection. - Fix resyncRegistration() in both flavors to call selectAndRegister() once before the server loop instead of once per server. - Add try/catch around JSON parsing in UnifiedPushReceiver.onMessage() to prevent crashes on malformed payloads. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use MessagingToken() wrapper for pushToken in PushProviderManager - Replace defaultServers with servers() suspend function - Fix test mocks to use coEvery for suspend functions - Replace Jackson with kotlinx.serialization in UnifiedPushMessageParsingTest - Update gradle lockfiles for new dependencies
8b2ffcc to
b832294
Compare
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The UnifiedPush connector depends on Tink which pulls in protobuf-java, conflicting with protobuf-javalite used by Firebase/gRPC in the full flavor. This exclusion was already applied to the minimal flavor. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adapt to upstream refactoring: MessagingTokenProvider, servers(), kotlinx.serialization, and new SettingsPresenter interface. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ExportedReceiver baseline entry for the UnifiedPush broadcast receiver (must be exported for distributors to send messages) and ObsoleteSdkInt for the automotive flavor SDK check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Test Results0 tests 0 ✅ 0s ⏱️ Results for commit 21e5e3e. ♻️ This comment has been updated with latest results. |
Address reviewer feedback: remove priority-based auto-selection in favor of a user-facing "Push provider" setting under Notifications. The user can now switch between FCM, UnifiedPush distributors, and WebSocket at any time without restarting the app. - Remove `priority` field from PushProvider interface - Replace hidden UnifiedPush-only preference with always-visible "Push provider" ListPreference showing all available providers - Add IgnoreViolationRule for UnifiedPush connector StrictMode violations - Fix UnifiedPush message parsing for nested JSON objects - Auto-restart WebSocket push channel when switching providers - Add fallback to empty token when FCM is unavailable - Fix toast shown incorrectly when disabling UnifiedPush - Update tests to reflect priority removal Tested on Pixel 9 Pro Fold (Android 16, GrapheneOS): - Switch WebSocket <-> UnifiedPush in both directions without restart - Notifications received on both providers in foreground and background - App killed: UnifiedPush still delivers via ntfy - Auto-fallback to WebSocket when ntfy topic is deleted Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for UnifiedPush as an alternative push notification provider, allowing users to receive notifications without relying on Google's FCM infrastructure. This is especially useful for the minimal/F-Droid flavor and privacy-conscious users.
Building on the work started by @lone-faerie in home-assistant#5261 and home-assistant#5301, this PR:
PushProviderinterface with priority-based selection via Dagger multibindingFcmPushProvider(full flavor),UnifiedPushProvider, andWebSocketPushProvider(fallback)PushProviderManagerto coordinate provider selection, registration, and server updatesLaunchActivity,LaunchPresenter, andSettingsPresenterBug fixes on top of the original implementation
push_encryptlogic inIntegrationRepositoryImpl— the condition was inverted, causing UnifiedPush notifications to never be encrypted even when keys were providedFcmPushProvider.isActive()— now correctly returnsfalsewhen UnifiedPush is the active providerresyncRegistration()—selectAndRegister()is now called once before the server loop instead of once per serverUnifiedPushReceiver.onMessage()for malformed JSON payloadsArchitecture
Related upstream: home-assistant#3174, home-assistant#5261, home-assistant#5301
Test plan
PushProviderManager(13 tests: selection, priority, switching, server updates)PushProviderinterface contracts (6 tests)🤖 Generated with Claude Code